﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using PluginInterface;
using SdmxMl.Common;
using SdmxMl.Manager;
using SdmxMl.Structure;
using Telerik.WinControls;
using Telerik.WinControls.UI;
using Telerik.WinControls.UI.Docking;
using Telerik.WinControls.UI.Export;


namespace SakeVar
{
    /// <summary> Espa plug-in control </summary>
    public partial class UcVarList : UserControl, IPlugin
    {
        #region Constants

        private const string CONCEPT_START_IDENTIFIER = "CS_SAKE_";

        #endregion

        #region Internal Members

        private ConceptSchemeType cstSakeVar;
        private Font fontTOT;
        private DlgCodeAndQuality dialogCodeQuality;

        private QuestGridCreator questCreator;
        private GridCreator gc;
        private string agencyTarget;
        #endregion

        #region Constructor

        public UcVarList()
        {
            InitializeComponent();
            agencyTarget = SdmxMl.Multiplexor.Mux.IsNewSmsRegistry ? "CH1" : "CH1_SAKE";

            try
            {
                toolWindowQuest.AllowedDockState = AllowedDockState.Docked | AllowedDockState.AutoHide;
                toolWindowQuest.Width = 650;
                toolWindowVariables.AllowedDockState = AllowedDockState.Docked;


                fontTOT = new Font("Arial", 8f, FontStyle.Bold);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region IPlugin Members

        /// <summary>Event is part of interface but not used </summary>
        public event PluginEvent PluginEventExposed
        {
            add { }
            remove { }
        }

        public void Init(System.Xml.XmlDocument xDoc, object obExtend)
        {
        }

        public UserControl VisualComponent()
        {
            return this;
        }

        public bool RequiresInit
        {
            get { return false; }
        }

        #endregion

        #region Control Load event

        private void UcVarList_Load(object sender, EventArgs e)
        {
            try
            {
                //Record event for selection change in main application tree
                ReferenceManager.TreeMgr.TreeSelect += new EventHandler(TreeMgr_TreeSelect);

                questCreator = new QuestGridCreator(radGridViewQuest, radDropDownListQid, radButtonNavQuest);
                gc = new GridCreator(radGridView);
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        
        #endregion

        #region Main Tree select event

        /// <summary>
        /// Selection Event in main tree. Uses it to define if HTML CATI is to be displayed
        /// </summary>
        void TreeMgr_TreeSelect(object sender, EventArgs e)
        {
            TreeView tv = ReferenceManager.TreeSdmx;
            if (tv == null)
                return;
            try
            {
                // Uncomment for importing variable catalog from SAKE Excel information
                //ModuleVarImport modImport = new ModuleVarImport(@"C:\doc\sake\aaaaa.xls");
                //modImport.ConstructVars(1);

                if (tv.SelectedNode != null)
                {
                    ConceptSchemeType cst = tv.SelectedNode.Tag as ConceptSchemeType;
                    if (cst != null && cst.AnnotationList.GetAnnotationType("QUEST") != null && cst.AnnotationList.GetAnnotationType("QUEST_LINK") != null)
                    {
                        cstSakeVar = cst;

                        // Get info for fetching associated questionnaire
                        Annotation a = cstSakeVar.AnnotationList.GetAnnotationType("QUEST");
                        bool isModule = a != null && a.Title.ToLower().IndexOf("mod") >= 0;

                        // Variable grid
                        gc.LoadUnboundData(cst, tv.SelectedNode.Nodes[0], isModule);


                        if (a == null || a.Url == null || string.IsNullOrEmpty(a.Title))
                            MessageBox.Show("Caution: No questionnaire is associated to this scheme.",
                                "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        else
                        {
                            questCreator.LoadGridData(a.Title, a.Url.ToString().Replace(@"file:///", ""));
                        }
                    }
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region Filtering Event

        /// <summary> Filtering eVent </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void radMenuItem2_Click(object sender, EventArgs e)
        {
            RadMenuItem menuItem = sender as RadMenuItem;
            if (menuItem != null)
                radGridView.EnableFiltering = menuItem.IsChecked;
        }
        #endregion

        #region Auto Expand Group Event

        private void radMenuItemAutoExpandGroups_Click(object sender, EventArgs e)
        {
            RadMenuItem menuItem = sender as RadMenuItem;
            if (menuItem != null)
                radGridView.MasterTemplate.AutoExpandGroups = menuItem.IsChecked;
        }

        #endregion

        #region Excel export

        /// <summary>Excel Export Event</summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void radMenuItemExportExcel_Click(object sender, EventArgs e)
        {
            RunExportToExcelML();
        }

        /// <summary> Export Grid to Excel </summary>
        private void RunExportToExcelML()
        {
            ExportToExcelML excelExporter = null;
            try
            {
                excelExporter = new ExportToExcelML(this.radGridView);
             //   excelExporter.ExcelCellFormatting += new Telerik.WinControls.UI.Export.ExcelML.ExcelCellFormattingEventHandler(exporter_ExcelCellFormatting);
                excelExporter.SummariesExportOption = SummariesOption.ExportAll;
                //set export settings
                excelExporter.ExportVisualSettings = true;
                excelExporter.ExportHierarchy = true;
                excelExporter.HiddenColumnOption = HiddenOption.DoNotExport;

                this.Cursor = Cursors.WaitCursor;
                saveFileDialog.Filter = "Excel (*.xls)|*.xls";
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    excelExporter.RunExport(saveFileDialog.FileName);

                    DialogResult dr = RadMessageBox.Show("The data in the grid was exported successfully. Do you want to open the file?",
                        "Export to Excel", MessageBoxButtons.YesNo, RadMessageIcon.Question);
                    if (dr == DialogResult.Yes)
                    {
                        System.Diagnostics.Process.Start(saveFileDialog.FileName);
                    }
                }
            }
            catch (Exception ex)
            {
                RadMessageBox.SetThemeName(this.radGridView.ThemeName);
                RadMessageBox.Show(this, ex.Message, "I/O Error", MessageBoxButtons.OK, RadMessageIcon.Error);
            }
            finally
            {
                this.Cursor = Cursors.Default;

          //      excelExporter.ExcelCellFormatting -= new Telerik.WinControls.UI.Export.ExcelML.ExcelCellFormattingEventHandler(exporter_ExcelCellFormatting);
            }
        }

        void exporter_ExcelCellFormatting(object sender, Telerik.WinControls.UI.Export.ExcelML.ExcelCellFormattingEventArgs e)
        {
            //Telerik.WinControls.UI.Export.ExcelML.BorderStyles border = new Telerik.WinControls.UI.Export.ExcelML.BorderStyles();
            /*
            if (e.GridRowInfoType == typeof(GridViewTableHeaderRowInfo))
            {
            }
            else if (e.GridCellInfo.ColumnInfo.Name == "Wave")
            {
                string period = e.GridCellInfo.RowInfo.Cells["Period"].Value.ToString();
              //  string period = string.Empty;
              //  if (radGridView.MasterTemplate.Rows[e.GridRowIndex].Cells["Period"].Value != null)
              //      period = radGridView.MasterTemplate.Rows[e.GridRowIndex].Cells["Period"].Value.ToString();

                e.ExcelStyleElement.InteriorStyle.Color = IsTrimestrial(period) ? Color.BlueViolet : Color.Orange;
            }
            else if (e.GridCellInfo.ColumnInfo.Name == "Text" || e.GridCellInfo.ColumnInfo.Name == "Thema")
            {
                e.ExcelStyleElement.AlignmentElement.WrapText = true;
            }

            */
                 
        }

        #endregion

        #region Cell Formatting

        void radGridView_CellFormatting2(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e)
        {
            if (e.CellElement.ColumnInfo.Name == "Wave")
            {
                string period = string.Empty;
                if (e.CellElement.RowInfo.Cells["Period"].Value != null)
                    period = e.CellElement.RowInfo.Cells["Period"].Value.ToString();

                e.CellElement.DrawFill = true;
                e.CellElement.BackColor = IsTrimestrial(period) ? Color.FromArgb(0xFF00FF) :Color.FromArgb(0xFF9900);
                e.CellElement.GradientStyle = Telerik.WinControls.GradientStyles.Solid;
            }
            else if (GridCreator.totListCol.Contains(e.CellElement.ColumnInfo.Name))
            {
                if (e.CellElement.ColumnInfo.Name == GridCreator.totListCol[0] || e.CellElement.ColumnInfo.Name == GridCreator.totListCol[2] || e.CellElement.ColumnInfo.Name == GridCreator.totListCol[4])
                {
                    e.CellElement.DrawFill = true;
                    e.CellElement.BackColor = Color.LightGray;
                    e.CellElement.GradientStyle = Telerik.WinControls.GradientStyles.Solid;
                    e.CellElement.TextAlignment = ContentAlignment.MiddleCenter;
                    if (e.CellElement.ColumnInfo.Name == GridCreator.totListCol[0] && IsTOTGroup(e.CellElement.RowInfo))
                        e.CellElement.Font = fontTOT;
                    else
                        e.CellElement.ResetValue(LightVisualElement.FontProperty, ValueResetFlags.Local);
                }
                else
                {
                    ResetCellElementValues(e.CellElement);
                }
            }
            else if (GridCreator.questListCol.Contains(e.CellElement.ColumnInfo.Name))
            {
                if (e.CellElement.ColumnInfo.Name == GridCreator.questListCol[0] || e.CellElement.ColumnInfo.Name == GridCreator.questListCol[2] || e.CellElement.ColumnInfo.Name == GridCreator.questListCol[4])
                {
                    e.CellElement.DrawFill = true;
                    e.CellElement.BackColor = Color.LightGray;
                    e.CellElement.GradientStyle = Telerik.WinControls.GradientStyles.Solid;
                }
                else
                {
                    ResetCellElementValues(e.CellElement);
                }
            }
            else
            {
                ResetCellElementValues(e.CellElement);
            }
        }

        void radGridView_CellFormatting(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e)
        {
            ResetCellElementValues(e.CellElement);

            if (e.CellElement.ColumnInfo.Name == "Wave")
            {
                string period = string.Empty;
                if (e.CellElement.RowInfo.Cells["Period"].Value != null)
                    period = e.CellElement.RowInfo.Cells["Period"].Value.ToString();

                e.CellElement.DrawFill = true;
                e.CellElement.BackColor = IsTrimestrial(period) ? Color.Orange : Color.PaleVioletRed;
                e.CellElement.GradientStyle = Telerik.WinControls.GradientStyles.Solid;
            }
            else if (GridCreator.totListCol.Contains(e.CellElement.ColumnInfo.Name))
            {
                if (e.CellElement.ColumnInfo.Name == GridCreator.totListCol[0] || e.CellElement.ColumnInfo.Name == GridCreator.totListCol[2] || e.CellElement.ColumnInfo.Name == GridCreator.totListCol[4])
                {
                    e.CellElement.DrawFill = true;
                    e.CellElement.BackColor = Color.LightGray;
                    e.CellElement.GradientStyle = Telerik.WinControls.GradientStyles.Solid;
                    //         e.CellElement.TextAlignment = ContentAlignment.MiddleCenter;
                    if (e.CellElement.ColumnInfo.Name == GridCreator.totListCol[0] && IsTOTGroup(e.CellElement.RowInfo))
                        e.CellElement.Font = fontTOT;
                }
            }
            else if (GridCreator.questListCol.Contains(e.CellElement.ColumnInfo.Name))
            {
                if (e.CellElement.ColumnInfo.Name == GridCreator.questListCol[0] || e.CellElement.ColumnInfo.Name == GridCreator.questListCol[2] || e.CellElement.ColumnInfo.Name == GridCreator.questListCol[4])
                {
                    e.CellElement.DrawFill = true;
                    e.CellElement.BackColor = Color.LightGray;
                    e.CellElement.GradientStyle = Telerik.WinControls.GradientStyles.Solid;
                }
            }
        }
            
        

        

        private void ResetCellElementValues(GridCellElement cellElement)
        {
            cellElement.ResetValue(LightVisualElement.DrawFillProperty, Telerik.WinControls.ValueResetFlags.Local);
            cellElement.ResetValue(VisualElement.BackColorProperty, ValueResetFlags.Local);
            cellElement.ResetValue(LightVisualElement.GradientStyleProperty, ValueResetFlags.Local);
         //   cellElement.ResetValue(LightVisualElement.TextAlignmentProperty, ValueResetFlags.Local);
            cellElement.ResetValue(LightVisualElement.FontProperty, ValueResetFlags.Local);
        }
        #endregion

        #region Helpers

        private bool IsTrimestrial (string s)
        {
            return s == "Vierteljährlich" || s == "Trimestrielle";
        }

        private bool IsTOTGroup(GridViewRowInfo rowInfo)
        {
            for (int i = 1; i < GridCreator.totListCol.Count; ++i)
                if (rowInfo.Cells[GridCreator.totListCol[i-1]].Value != rowInfo.Cells[GridCreator.totListCol[i]].Value)
                      return false;
            return true;
        }
        #endregion

        #region Navigation Events

        private void radMenuButtonItemNavigate_Click(object sender, EventArgs e)
        {
            try
            {
                bool toCodelist = sender == radMenuButtonItemNavCodelist || Control.ModifierKeys == Keys.Control;

                if (radGridView.CurrentCell != null && 
                    GridCreator.totListCol.Contains(radGridView.CurrentCell.ColumnInfo.Name) && 
                    radGridView.CurrentCell.Value != null )
                {
                    ConceptType concept = cstSakeVar.ConceptList.LocateItem(radGridView.CurrentCell.Value.ToString()) as ConceptType;
                    if (concept != null)
                    {
                        // Do we go to codelist or concept
                        if (toCodelist)
                        {
                            if (concept.CoreRepresentation.IsFilled)
                            {
                                NavigateTodetail(UrnManager.FullIdToUrn(SdmxArtefactType.CodeLists.ToString(),
                                concept.CoreRepresentation.FullIdent, null, null));
                                if (ReferenceManager.TreeSdmx.SelectedNode.Tag is CodeListType)
                                    ReferenceManager.TreeSdmx.SelectedNode.ExpandAll();
                                else
                                    MessageBox.Show("Unable to locate codelist: " + concept.CoreRepresentation.FullIdent, "Caution", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            }
                            else
                            {
                                MessageBox.Show("No codelist associated with: " + concept.Id, "Caution", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        
                            }
                        }
                        else
                        {
                            NavigateTodetail(UrnManager.FullIdToUrn(SdmxArtefactType.Concepts.ToString(),
                            cstSakeVar.FullIdent, concept, null));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void NavigateTodetail(string urn)
        {
            try
            {
                if (ReferenceManager.TreeMgr.PanelDetail != null)
                {
                    ReferenceManager.TreeMgr.PanelDetail.TabControlDetail.SelectedIndex = 0;
                    ReferenceManager.TreeMgr.PanelDetail.UpdateNodeTag(ReferenceManager.TreeSdmx.SelectedNode);
                    ReferenceManager.TreeMgr.PanelDetail.BindFromNode(null);
                }

                // If already in memory, navigate otherwhile get from registry
                UrnParser p = new UrnParser(urn);
                if (p.IsSupported)
                {
                    // If already in memory, navigate otherwhile get from regidtry
                    if (NavigationManager.LocatenavigateProject(p.ArType, p.FullIdent, p) == null)
                        NavigationManager.NavigateWithRegistry(p.ArType, p.FullIdent, true, p);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region Cell double-click Event

        private void radGridView_CellDoubleClick(object sender, GridViewCellEventArgs e)
        {
            if (radGridView.CurrentCell != null && radGridView.CurrentCell.Value != null)
            {
                if (GridCreator.totListCol.Contains(radGridView.CurrentCell.ColumnInfo.Name))
                    radMenuButtonItemNavigate_Click(radMenuButtonItemNavConcept, EventArgs.Empty);
                else if (GridCreator.questListCol.Contains(radGridView.CurrentCell.ColumnInfo.Name))
                {
                    List<string> listId = questCreator.GetQidList(radGridView.CurrentCell.Value.ToString());
                }
            }
        }
        #endregion

        #region Codes and Quality Display

        private void radMenuItemViewCodesQuality_Click(object sender, EventArgs e)
        {
            try
            {
                if (radGridView.CurrentCell != null &&
                    GridCreator.totListCol.Contains(radGridView.CurrentCell.ColumnInfo.Name) &&
                    radGridView.CurrentCell.Value != null)
                {
                    string conceptId = radGridView.CurrentCell.Value.ToString();
                    ConceptType concept = cstSakeVar.ConceptList.LocateItem(conceptId) as ConceptType;
                    if (concept != null)
                    {
                        ConceptType conceptQuality = cstSakeVar.ConceptList.LocateItem(concept.Id + "_F") as ConceptType;
                        if (conceptQuality != null)
                            if (conceptQuality.Parent == null || conceptQuality.Parent != concept.Id)
                                conceptQuality = null;
                        if (concept.CoreRepresentation.IsFilled == false &&
                            (conceptQuality == null || conceptQuality.CoreRepresentation.IsFilled == false))
                        {
                            MessageBox.Show("No code or quality code associated with: " + concept.Id, "Caution", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

                        }
                        else
                        {
                            // Fetch availables codelists
                            SmManager sm = ReferenceManager.GetSmContainerImage();

                            CodeListType cltCodes = null;
                            CodeListType cltQuality = null;
                            if (concept.CoreRepresentation.IsFilled)
                                cltCodes = sm.GetArtefact(SdmxArtefactType.CodeLists, concept.CoreRepresentation, true) as CodeListType;
                            if (conceptQuality != null && conceptQuality.CoreRepresentation.IsFilled)
                                cltQuality = sm.GetArtefact(SdmxArtefactType.CodeLists, conceptQuality.CoreRepresentation, true) as CodeListType;


                                dialogCodeQuality = new DlgCodeAndQuality();
                                dialogCodeQuality.Update(cltCodes, cltQuality);
                                dialogCodeQuality.ShowDialog();
                            /*
                                dialogCodeQuality.FormClosed += new FormClosedEventHandler(dialogCodeQuality_FormClosed);
                            }
                            dialogCodeQuality.Update(cltCodes, cltQuality);
                            dialogCodeQuality.WindowState = FormWindowState.Normal;
                            dialogCodeQuality.Focus();
                            dialogCodeQuality.Show();
                             */

                        }
                    }
                    else
                        MessageBox.Show("Unable to locate concept: " + conceptId, "Caution", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
        void dialogCodeQuality_FormClosed(object sender, FormClosedEventArgs e)
        {
            dialogCodeQuality = null;
        }
        #endregion

        #region Synchronize to question

        private void radGridView_CellClick(object sender, GridViewCellEventArgs e)
        {
            try
            {
                if (radGridView.CurrentCell != null && radGridView.CurrentCell.Value != null)
                {
                    if (GridCreator.questListCol.Contains(radGridView.CurrentCell.ColumnInfo.Name))
                    {
                        questCreator.GetQidList(radGridView.CurrentCell.Value.ToString());
                    }
                    else if (GridCreator.totListCol.Contains(radGridView.CurrentCell.ColumnInfo.Name))
                    {
                        // get index
                        int index = GridCreator.totListCol.IndexOf(radGridView.CurrentCell.ColumnInfo.Name);
                        if (index >= 0)
                        {
                            if (radGridView.CurrentRow.Cells[GridCreator.questListCol[index]].Value != null)
                                questCreator.GetQidList(radGridView.CurrentRow.Cells[GridCreator.questListCol[index]].Value.ToString());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region SAS / SPSS Export

        /// <summary>SAS / SPSS export event. Raise dialog box dedicated to export </summary>
        private void radMenuItemSAS_Click(object sender, EventArgs e)
        {
            try
            {

                if (cstSakeVar != null && gc != null)
                {
                    DlgSasExport aDlg = new DlgSasExport(gc);
                    aDlg.ShowDialog();
                }
                else
                    MessageBox.Show("Sorry. No ConceptScheme correctly loaded", "Error", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        private void radMenuItem3_Click(object sender, EventArgs e)
        {
            try
            {
                SmManager sm = ReferenceManager.GetSmContainerImage();
                ArtefactRefTyped art = new ArtefactRefTyped(SdmxArtefactType.MetadataSet, "CH1_SAKE+MS_Q_MAIN+2012.0");
                SdmxMl.GenericMetadata.MetadataSetType metaset = sm.GetArtefact(art.Type, art) as SdmxMl.GenericMetadata.MetadataSetType;
                if (metaset != null)
                {
                    // Iterate ConceptScheme
                    foreach (ConceptType c in cstSakeVar.ConceptList)
                    {
                        TreatConcept(sm, metaset, c);
                    }
                }



                // Get annotation of type QUEST_PRINT

                // Locate metaset row
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


        }

        private void TreatConcept(SmManager sm, SdmxMl.GenericMetadata.MetadataSetType metaset, ConceptType c)
        {
            Annotation a = c.AnnotationList.GetAnnotationType("QUEST_PRINT");
            if (a != null && a.Title.Length > 0)
            {
                List<string> listQuest = questCreator.GetQidList(a.Title);
                foreach (string qid in listQuest)
                {
                    // Get metaset question
                    foreach (SdmxMl.GenericMetadata.AttributeValueSetType atv in metaset.AttributeValueSetList)
                    {
                        if (atv.TargetValuesTypeList[2].Value == qid)
                        {
                            SdmxMl.GenericMetadata.ReportedAttributeType rpt = atv.ReportedAttributeList.GetReportedAttributeOfConcept("CONCEPT_URN");
                            string urn = UrnManager.FullIdToUrn(SdmxArtefactType.Concepts.ToString(), cstSakeVar.FullIdent, c, null);
                            rpt.Value = new MultiLang(urn);

                            // Codelist reference also ?
                            if (c.CoreRepresentation.IsFilled)
                            {
                                rpt = atv.ReportedAttributeList.GetReportedAttributeOfConcept("CODELIST_URN");
                                CodeListType clt = sm.GetArtefact(SdmxArtefactType.CodeLists, c.CoreRepresentation) as CodeListType;
                                urn = UrnManager.FullIdToUrn(SdmxArtefactType.CodeLists, clt.FullIdent);
                                rpt.Value = new MultiLang(urn);
                            }
                            break;
                        }
                    }
                }


            }

        }

    }
}
